package com.fimmlps.reronge.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fimmlps.reronge.dto.*;
import com.fimmlps.reronge.entity.EntryUser;
import com.fimmlps.reronge.entity.EntryUserApply;
import com.fimmlps.reronge.entity.EntryUserChat;
import com.fimmlps.reronge.entity.EntryUserSubscribe;
import com.fimmlps.reronge.service.*;
import com.fimmlps.reronge.vo.TResponseVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/entryUser")
public class EntryUserController {
    @Autowired
    private IEntryUserService userService;

    @Autowired
    private IEntryUserApplyService userApplyService;

    @Autowired
    private IEntryUserSubscribeService subscribeService;

    @Autowired
    private IEntryUserChatService userChatService;

    @Autowired
    private IEntrySingleService entrySingleService;

    @Autowired IActorSingleService actorSingleService;


    //获取今日数据
    @GetMapping("/getRerongeData")
    public TResponseVo<MainDataDto> getRerongeData(){
        try {
            MainDataDto dto = new MainDataDto();
            int totalActor = (int) actorSingleService.count();
            int totalEntry = (int) entrySingleService.count();
            int totalUser = (int)userService.count();
            dto.setTotalActors(totalActor);
            dto.setTotalEntries(totalEntry);
            dto.setTotalUsers(totalUser);
            return TResponseVo.success(dto);
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //注册
    @PostMapping("/register")
    public TResponseVo<EntryUser> register(@RequestBody Map<String,Object> map){
        try {
            String username = (String) map.get("username");
            String password = (String) map.get("password");
            EntryUser userTry = userService.getUserByName(username);
            if(userTry!=null){
                return TResponseVo.error(400,"用户已存在！");
            }
            EntryUser user = new EntryUser();
            user.setUserName(username);
            String encodedPassword = new BCryptPasswordEncoder().encode(password);
            user.setUserPassword(encodedPassword);
            user.setUserCreateTime(LocalDateTime.now());
            user.setUserEditor(0);
            user.setUserAdmin(0);
            userService.save(user);
            user.setUserPassword(password);
            return new TResponseVo<>(200,user,"注册成功，即将返回登录！");

        }catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    @PostMapping("/saveUser")
    public TResponseVo<EntryUser> saveUser(@RequestBody EntryUser user){
        try {
            String password = user.getUserPassword();
            String encodedPassword = new BCryptPasswordEncoder().encode(password);
            user.setUserPassword(encodedPassword);
            userService.save(user);
            return new TResponseVo<>(200,user,"原始密码："+password);
        }catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    @GetMapping("/getAllUsers")
    public TResponseVo<List<EntryUser>> getAllUsers(){
        try {
            return TResponseVo.success(userService.list());
        }catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    @PostMapping("/updateUser")
    public TResponseVo<EntryUser> updateUser(@RequestBody EntryUser user){
        try {
            String password = user.getUserPassword();
            String encodedPassword = new BCryptPasswordEncoder().encode(password);
            user.setUserPassword(encodedPassword);
            userService.updateById(user);
            user.setUserPassword(password);
            return new TResponseVo<>(200,user,"用户信息更改成功，变更用户为："+user.getUserName());
        }catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 百科编辑权限检查
    //参数 检查用户名 senderName
    @PostMapping("/checkEditor")
    public TResponseVo<String> checkEditor(@RequestBody Map<String,Object> map){
        try {
            String senderName = (String) map.get("senderName");
            EntryUser sender = userService.getUserByName(senderName);
            if(sender.getUserAdmin()==1||sender.getUserEditor()==1)
                return TResponseVo.success("拥有权限");
            return TResponseVo.error(400,"未拥有权限");
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 百科编辑权申请
    //参数 申请用户名 senderName
    @PostMapping("/applyEditor")
    public TResponseVo<String> applyEditor(@RequestBody Map<String,Object> map){
        try {
            String senderName = (String) map.get("senderName");
            EntryUser sender = userService.getUserByName(senderName);
            EntryUserApply apply = userApplyService.getApplyBySendID(sender.getUserId());
            if(apply!=null){
                return TResponseVo.success("您已申请过权限，请等待审核");
            }
            apply = new EntryUserApply();
            apply.setEntryApplyType(1);
            apply.setEntryUserSenderId(sender.getUserId());
            apply.setEntryUserSendeeId(0);
            apply.setEntryApplyResult(0);
            apply.setCreateTime(LocalDateTime.now());
            userApplyService.save(apply);
            return TResponseVo.success("权限申请成功，请等待审核");
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 编辑权限同意
    //参数 申请号ID entryUserApplyId 处理结果 result （1-同意 2-拒绝）
    @PostMapping("/giveEditor")
    public TResponseVo<String> giveEditor(@RequestBody Map<String,Object> map){
        try {
            int entryUserApplyId = (int) map.get("entryUserApplyId");
            int result = (int) map.get("result");
            if(result!=1&&result!=2){
                return TResponseVo.success("操作不合法");
            }
            EntryUserApply apply = userApplyService.getById(entryUserApplyId);
            if(apply==null){
                return TResponseVo.success("该请求不存在");
            }
            if(apply.getEntryApplyResult()!=0){
                return TResponseVo.success("该请求已处理");
            }
            apply.setEntryApplyResult(result);
            userApplyService.updateById(apply);
            if(result==1){
                EntryUser user = userService.getById(apply.getEntryUserSenderId());
                user.setUserEditor(1);
                userService.updateById(user);
                return TResponseVo.success("同意申请成功");
            }
            else
                return TResponseVo.success("拒绝申请成功");
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 好友申请
    //参数 申请用户名 senderName 被申请用户名 sendeeName
    @PostMapping("/applyUser")
    public TResponseVo<String> applyUser(@RequestBody Map<String,Object> map){
        try {
            String senderName = (String) map.get("senderName");
            String sendeeName = (String) map.get("sendeeName");
            EntryUser sender = userService.getUserByName(senderName);
            EntryUser sendee = userService.getUserByName(sendeeName);
            if(sendee==null){
                return TResponseVo.success("被申请用户不存在");
            }
            if(subscribeService.isFriend(sender.getUserId(),sendee.getUserId())){
                return TResponseVo.success("你们已经是好友");
            }
            EntryUserApply apply = userApplyService.getApplyBySSIDs(sender.getUserId(),sendee.getUserId());
            if(apply!=null){
                return TResponseVo.success("您已向该用户申请过好友");
            }
            apply = userApplyService.getApplyBySSIDs(sendee.getUserId(),sender.getUserId());
            if(apply!=null){
                return TResponseVo.success("对方已向您申请好友");
            }
            apply = new EntryUserApply();
            apply.setEntryApplyType(0);
            apply.setEntryUserSenderId(sender.getUserId());
            apply.setEntryUserSendeeId(sendee.getUserId());
            apply.setEntryApplyResult(0);
            apply.setCreateTime(LocalDateTime.now());

            userApplyService.save(apply);
            return TResponseVo.success("好友申请成功");
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 好友同意
    //参数 好用申请号ID entryUserApplyId 处理结果 result （1-同意 2-拒绝）
    @PostMapping("/subscribeUser")
    public TResponseVo<String> subscribeUser(@RequestBody Map<String,Object> map){
        try {
            int entryUserApplyId = (int) map.get("entryUserApplyId");
            int result = (int) map.get("result");
            if(result!=1&&result!=2){
                return TResponseVo.success("操作不合法");
            }
            EntryUserApply apply = userApplyService.getById(entryUserApplyId);
            if(apply==null){
                return TResponseVo.success("该请求不存在");
            }
            if(apply.getEntryApplyResult()!=0){
                return TResponseVo.success("该请求已处理");
            }
            apply.setEntryApplyResult(result);
            userApplyService.updateById(apply);
            if(result==1){
                EntryUserSubscribe subscribe = new EntryUserSubscribe();
                subscribe.setUserId(apply.getEntryUserSenderId());
                subscribe.setSubedUserId(apply.getEntryUserSendeeId());
                subscribeService.save(subscribe);
                return TResponseVo.success("同意申请成功");
            }
            else
                return TResponseVo.success("拒绝申请成功");
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 获取未处理的消息
    //参数 用户名 userName
    @PostMapping("/getMessages")
    public TResponseVo<TotalMessageDto> getMessages(@RequestBody Map<String,Object> map){
        try {
            String userName = (String) map.get("userName");
            EntryUser user = userService.getUserByName(userName);
            TotalMessageDto dto = new TotalMessageDto();
            dto.setUserName(userName);
            dto.setMessages(new ArrayList<>());
            ArrayList<MessageDto> messageDtos = new ArrayList<>();
            //好友类请求
            List<EntryUserApply> applies = userApplyService.list(new QueryWrapper<EntryUserApply>().eq("entry_apply_type",0)
                    .eq("entry_user_sendee_id",user.getUserId()));
            for(EntryUserApply apply:applies){
                //跳过已处理的请求
                if(apply.getEntryApplyResult()!=0)
                    continue;
                EntryUser sender = userService.getById(apply.getEntryUserSenderId());
                if(sender!=null){
                    messageDtos.add(new MessageDto(apply,sender,user));
                }
            }
            dto.getMessages().addAll(messageDtos);
            //权限类请求 仅管理员账户可以查看
            if(user.getUserAdmin()==1){
                messageDtos.clear();
                applies = userApplyService.list(new QueryWrapper<EntryUserApply>().eq("entry_apply_type",1)
                        .eq("entry_apply_result",0));
                for(EntryUserApply apply:applies){
                    EntryUser sender = userService.getById(apply.getEntryUserSenderId());
                    if(sender!=null){
                        messageDtos.add(new MessageDto(apply,sender));
                    }
                }
                dto.getMessages().addAll(messageDtos);
            }
            return TResponseVo.success(dto);
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 获取所有好友
    //参数 用户名 userName
    @PostMapping("/getFriends")
    public TResponseVo<TotalFriendDto> getFriends(@RequestBody Map<String,Object> map){
        try {
            String userName = (String) map.get("userName");
            EntryUser user = userService.getUserByName(userName);

            TotalFriendDto dto = new TotalFriendDto();
            dto.setUserName(userName);
            ArrayList<EntryUserSubscribe> ids = subscribeService.getAllFriends(user.getUserId());
            ArrayList<FriendDto> friendDtos = new ArrayList<>();
            for(EntryUserSubscribe id:ids){
                int anotherId;
                if(id.getUserId()!=user.getUserId()){
                    anotherId = id.getUserId();
                }
                else{
                    anotherId = id.getSubedUserId();
                }
                EntryUser anotherUser = userService.getById(anotherId);
                EntryUserChat chat = null;
                if(anotherUser!=null){
                    if(id.getLatestChatId()!=null&&id.getLatestChatId()>0){
                        chat = userChatService.getById(id.getLatestChatId());
                    }
                    FriendDto fDto = new FriendDto(anotherUser,chat);
                    friendDtos.add(fDto);
                }
            }
            friendDtos.sort(Comparator.comparing(FriendDto::getLatestTime).reversed());
            dto.setFriends(friendDtos);
            return TResponseVo.success(dto);
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 发起单次聊天（包括转发，一概入内！）
    //参数 发起用户 userName 接受用户 userId 类型 type(0-chat 1-actor 2-entry) 聊天内容 content 额外参数 extraId
    @PostMapping("/chat")
    public TResponseVo<ChatDto> chat(@RequestBody Map<String,Object> map){
        try {
            String userName = (String) map.get("userName");
            int userId = (int)map.get("userId");
            int type = (int)map.get("type");
            String content = (String)map.get("content");
            int extraId = (int)map.get("extraId");

            EntryUser chater = userService.getUserByName(userName);
            EntryUser chatee = userService.getById(userId);

            EntryUserChat chat = new EntryUserChat();
            chat.setChaterUserId(chater.getUserId());
            chat.setChateeUserId(chatee.getUserId());
            chat.setChatType(type);
            chat.setChatContent(content);
            chat.setChatExtraId(extraId);
            chat.setCreateTime(LocalDateTime.now());

            userChatService.save(chat);

            //同时更新Subscriber的最新
            EntryUserSubscribe subscribe = subscribeService.getByIDs(chater.getUserId(),chatee.getUserId());
            if(subscribe!=null){
                subscribe.setLatestChatId(chat.getEntryUserChatId());
                subscribeService.updateById(subscribe);
            }

            ChatDto dto = new ChatDto(chat,chater,chatee);
            return TResponseVo.success(dto);

        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 获取与某个好友的最新30条记录
    //参数 发起用户 userName 被查询用户 userId
    @PostMapping("/getChats")
    public TResponseVo<TotalChatDto> getChats(@RequestBody Map<String,Object> map){
        try {
            String userName = (String) map.get("userName");
            int userId = (int)map.get("userId");
            EntryUser finder = userService.getUserByName(userName);
            EntryUser findee = userService.getById(userId);

            TotalChatDto dto = new TotalChatDto();
            dto.setUserName(userName);
            QueryWrapper<EntryUserChat> queryWrapper = new QueryWrapper<>();
            queryWrapper.and(i -> i.eq("chater_user_id",finder.getUserId()).eq("chatee_user_id",findee.getUserId()))
                            .or(i -> i.eq("chatee_user_id",finder.getUserId()).eq("chater_user_id",findee.getUserId()));
            queryWrapper.orderByAsc("create_time");
            Page<EntryUserChat> thirty = new Page<>(1,30);
            IPage<EntryUserChat> iPage = userChatService.page(thirty,queryWrapper);
            List<EntryUserChat> totals = iPage.getRecords();
            ArrayList<ChatDto> dtoList = new ArrayList<>();
            for(EntryUserChat chat:totals){
                ChatDto d = null;
                if(chat.getChaterUserId()==finder.getUserId() && chat.getChateeUserId()== findee.getUserId()){
                    d = new ChatDto(chat,finder,findee);
                }
                else if (chat.getChaterUserId()==findee.getUserId() && chat.getChateeUserId()== finder.getUserId()){
                    d = new ChatDto(chat,findee,finder);
                }
                if(d!=null)
                    dtoList.add(d);
            }
            dto.setChats(dtoList);
            return TResponseVo.success(dto);
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 获取用户信息
    //参数 用户名 userName
    @PostMapping("/obtainUserInfo")
    public TResponseVo<EntryUser> obtainUserInfo(@RequestBody Map<String,Object> map){
        try {
            String userName = (String) map.get("userName");
            EntryUser user = userService.getUserByName(userName);
            if(user==null){
                return TResponseVo.error(400,"用户不存在");
            }
            return TResponseVo.success(user);
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }

    //POST 上传头像的URL
    //参数 用户名 userName 用户头像URL url
    @PostMapping("/updateUserHead")
    public TResponseVo<EntryUser> updateUserHead(@RequestBody Map<String,Object> map){
        try {
            String userName = (String) map.get("userName");
            String url = (String)map.get("url");
            EntryUser user = userService.getUserByName(userName);
            if(user==null){
                return TResponseVo.error(400,"用户不存在");
            }
            user.setUserHeadUrl(url);
            userService.updateById(user);
            return TResponseVo.success(user);
        }
        catch (Exception e){
            return TResponseVo.error(500,e.getMessage());
        }
    }
}
